package chapter18;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

public class Directory {
	/**
	 * 
	 * @param dir
	 * @param regex
	 * @return dir目录下符合{@code regex}的文件数组
	 * chuanwei.huang
	 */
	public static File[] local(File dir, final String regex) {
		Pattern pattern = Pattern.compile(regex);
		return dir.listFiles((dirs, name) -> {
			return pattern.matcher(new File(name).getName()).matches();
		});
	}

	public static File[] local(String path, final String regex) {
		return local(new File(path), regex);
	}
	
	public static class TreeInfo implements Iterable<File> {
		public List<File> files = new ArrayList<>();
		public List<File> dirs = new ArrayList<>();
		@Override
		public Iterator<File> iterator() {
			return files.iterator();
		}
		void addAll(TreeInfo other) {
			files.addAll(other.files);
			dirs.addAll(other.dirs);
		}
		
		public String toString() {
			return "dirs: " + dirs + "\n files: " + files;
		}
		
		public static TreeInfo walk(String start, String regex) {
			return recurseDirs(new File(start), regex);
		}
		
		public static TreeInfo walk(File start, String regex) {
			return recurseDirs(start, regex);
		}
		
		public static TreeInfo walk(File start) {
			return recurseDirs(start, ".*");
		}
		
		public static TreeInfo walk(String start) {
			return recurseDirs(new File(start), ".*");
		}

		/**
		 * 递归的过滤{@code startDir} 目录下符合{@code regex}的文件(非文件夹); 
		 * @param startDir
		 * @param regex
		 * @return
		 * chuanwei.huang
		 */
		private static TreeInfo recurseDirs(File startDir, String regex) {
			TreeInfo result = new TreeInfo();
			for(File item: startDir.listFiles()) {
				if(item.isDirectory()) {
					result.dirs.add(item);
					result.addAll(recurseDirs(item, regex));
				}else {
					if(item.getName().matches(regex))
						result.files.add(item);
				}
			}
			return result;
		}
		
		public static void main(String[] args) {
			if(args.length == 0) {
				System.out.println(walk("."));
				
			}else {
				System.out.println(walk(args[0]));
			}
		}
	}
	
	
}
